import { useContext, useLayoutEffect, useRef, useState } from 'react';
import { Button, Form, Space } from 'antd';
import { FormModalContext } from './FormModalContext';
import { isEqual } from 'lodash-es';
import { formatValues } from './utils';
import useFormItems from './useFormItems';
import type { AnyObject, FormModalProps } from '../type';
import type { HookAPI } from 'antd/es/modal/useModal';

const FormContent = <T extends AnyObject>(
	props: Required<
		Pick<
			FormModalProps<T>,
			| 'form'
			| 'formItems'
			| 'formProps'
			| 'columnGap'
			| 'formHeadSlot'
			| 'formFooterSlot'
			| 'footer'
			| 'closeWarnProps'
			| 'bodyHeight'
			| 'onConfirm'
		>
	> & {
		full: boolean;
		closeModal: HookAPI;
	}
) => {
	const {
		form,
		formProps,
		formItems,
		columnGap,
		formHeadSlot,
		formFooterSlot,
		footer,
		closeWarnProps,
		full,
		closeModal,
		bodyHeight,
		onConfirm
	} = props;
	const { store, close } = useContext(FormModalContext);

	// 确认按钮loading
	const [confirmLoading, setConfirmLoading] = useState(false);
	// 内容区高度
	const [height, setHeight] = useState(0);
	// 记录Confirm是否成功
	const confirmedRef = useRef(false);

	// 初始化内容区高度
	useLayoutEffect(() => {
		if (store.open) {
			if (bodyHeight) {
				setHeight(bodyHeight);
				return;
			}
			const mainHeight = window.innerHeight || document.body.offsetHeight;
			const result = mainHeight - 200 - 110;
			setHeight(result);
		} else {
			confirmedRef.current = false;
		}
	}, [store.open, bodyHeight]);

	// 生成Form组件内容
	const formContent = useFormItems({ formItems, columnGap });

	// Confirm
	const handleConfirm = async () => {
		try {
			setConfirmLoading(true);
			const values = await form.validateFields();
			const formData = { ...store.initData, ...values };
			const result = formatValues(formData, formItems);
			await onConfirm(result);
			confirmedRef.current = true;
		} finally {
			setConfirmLoading(false);
		}
	};

	// Close
	const handleClose = () => {
		// 如果提交已成功，不再拦截
		if (confirmedRef.current) return close();

		const { initData } = store;
		const values = form.getFieldsValue(true);
		// 对比目前表单值是否与初始值一致
		const same = isEqual(initData, values);
		// 相同直接关闭，不同则提示内容未保存
		if (same) {
			close();
		} else {
			closeModal.confirm({
				title: '内容未保存，是否确认关闭？',
				centered: true,
				onOk: close,
				...closeWarnProps
			});
		}
	};

	return (
		<div className="jp-form_modal-container">
			<div
				className="jp-form_modal-content"
				style={{
					height: full ? 'calc(100vh - 162px)' : height,
					overflowY: 'auto',
					padding: 16
				}}
			>
				{formHeadSlot && <div className="head-slot">{formHeadSlot}</div>}
				<Form form={form} labelCol={{ style: { width: 100 } }} {...formProps}>
					{formContent}
				</Form>
				{formFooterSlot && <div className="footer-slot">{formFooterSlot}</div>}
			</div>
			{footer !== null && (
				<div
					className="jp-form_modal-footer"
					style={{ padding: 16, textAlign: 'right', borderTop: '1px solid #eaeaea' }}
				>
					<Space>
						<Button type="primary" ghost onClick={handleClose}>
							关闭
						</Button>
						{footer || (
							<Button key="confirm" type="primary" loading={confirmLoading} onClick={handleConfirm}>
								确定
							</Button>
						)}
					</Space>
				</div>
			)}
		</div>
	);
};

export default FormContent;
